package uz.rt.physics;

import uz.rt.units.Length;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class CurveFileOutputWriter
{

    public synchronized void writePdd(String filename, Pdd pdd, Length.Unit unit) throws IOException
    {
        File f = new File(filename);
        writePdd(f, pdd, unit);
    }

    public synchronized void writePdd(File file, Pdd pdd, Length.Unit unit) throws IOException
    {
        if (pdd == null) throw new IOException("Pdd object was not initialised, no data will be written out.");
        else
        {
            pdd.equaliseScales(unit);
            pdd.sort();
        }
        if (!file.exists())
        {
            if(!file.delete()) throw new IOException("Unable to delete existing file");
        }
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        bw.write(CurveIO.commentToken + " pdd data points"+System.getProperty("line.separator"));
        writePddHeader(bw, pdd, unit);
        for (int i = 0; i < pdd.size(); i++)
        {
            bw.write(pdd.at(i).getX().getValue() + ", " + pdd.at(i).getY() + System.getProperty("line.separator"));
            bw.flush();
        }
        bw.close();
    }

    private synchronized void writePddHeader(BufferedWriter bw, Pdd pdd, Length.Unit unit) throws IOException
    {
        if (pdd.getEnergy() == null) throw new IOException("Pdd energy was not initialised");
        if (unit == null) throw new IOException("Pdd unit was not initialised");
        bw.write("energy: " + pdd.getEnergy().toString() + System.getProperty("line.separator"));
        bw.flush();
        if (unit == Length.Unit.mm) bw.write("unit: mm"+System.getProperty("line.separator"));
        else if (unit == Length.Unit.cm) bw.write("unit: cm"+System.getProperty("line.separator"));
        bw.flush();
    }


    public synchronized void writeTpr(File file, Tpr tpr, Length.Unit unit) throws IOException
    {
        if (tpr == null) throw new IOException("Pdd object was not initialised, no data will be written out.");
        else
        {
            tpr.equaliseScales(unit);
            tpr.sort();
        }
        if (!file.exists())
        {
            if(!file.delete()) throw new IOException("Unable to delete existing file");
        }
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        bw.write(CurveIO.commentToken + " tpr data points"+System.getProperty("line.separator"));
        writeTprHeader(bw, tpr, unit);
        for (int i = 0; i < tpr.size(); i++)
        {
            bw.write(tpr.at(i).getX().getValue() + ", " + tpr.at(i).getY() + System.getProperty("line.separator"));
            bw.flush();
        }
        bw.close();
    }

    private synchronized void writeTprHeader(BufferedWriter bw, Tpr tpr, Length.Unit unit) throws IOException
    {
        if (tpr.getEnergy()== null) throw new IOException("Tpr energy was not initialised");
        if (unit == null) throw new IOException("Pdd unit was not initialised");
        if(tpr.getEquivalentFieldSize() == null) throw new NullPointerException("Tpr equivalent square field size cannot be null");
        if(tpr.getReferenceDepth() == null) throw new NullPointerException("Tpr reference depth cannot be null");

        bw.write("energy: " + tpr.getEnergy().toString() + System.getProperty("line.separator"));
        bw.flush();
        if (unit == Length.Unit.mm) bw.write("unit: mm"+System.getProperty("line.separator"));
        else if (unit == Length.Unit.cm) bw.write("unit: cm"+System.getProperty("line.separator"));
        bw.flush();
        bw.write("equivalent field size: " + tpr.getEquivalentFieldSize().scaled(unit));
        bw.write("reference depth: " + tpr.getReferenceDepth().scaled(unit));
    }
}
